#include <taskManager.h>
#include <task.h>
#include <log.h>
#include <modules.h>
#include <framework.h>
#include <utils.h>
#include <keyMap.h>
#include <commands.h>
#include <cnotify.h>

EXTERN_C_BEGIN
    STATUS objTaskEntry(const char *objTaskName, FUNCPTR func, void *arg,
                        const char *file, int len)
    {
        COND_CHECK_RET_ERROR((func == nullptr));
        TaskPtr task = std::make_shared<Task>(utils::format("t%s", objTaskName).c_str(), func, arg);
        COND_CHECK_RET_ERROR((task == nullptr));

        try
        {
            task->execute();
            LOG_TRACE("Task created: %s (ID: %u)", objTaskName, task->getThreadId());
            return OK;
        }
        catch (const std::exception& e)
        {
            LOG_ERROR("Failed to create thread for task %s: %s", objTaskName, e.what());
            return RET_ERROR;
        }
    }
EXTERN_C_END

STATUS TaskManager::addTask(TaskPtr task)
{
    COND_CHECK_RET_ERROR((task == nullptr));

    std::lock_guard<std::mutex> lock(m_objectLock);
    m_tasks[task->getThreadId()] = task;
    return OK;
}

STATUS TaskManager::removeTask(Task::TASK_ID taskId)
{
    std::lock_guard<std::mutex> lock(m_objectLock);
    auto it = m_tasks.find(taskId);

    COND_CHECK_RET_ERROR((it == m_tasks.end()));

    m_tasks.erase(it);
    return OK;
}

size_t TaskManager::getTaskCount() const
{
    std::lock_guard<std::mutex> lock(m_objectLock);
    return m_tasks.size();
}

TaskPtr TaskManager::findTask(Task::TASK_ID taskId)
{
    std::lock_guard<std::mutex> lock(m_objectLock);
    auto it = m_tasks.find(taskId);
    if (it != m_tasks.end()) {
        return it->second;
    }
    return nullptr;
}

STATUS TaskManager::dump(TextTable &t)
{
    t.setTableName("objTaskMgr");
    t.addHeader("taskName");
    t.addHeader("taskId");
    t.addHeader("objPtr");
    t.addHeader("status").endOfRow();

    std::lock_guard<std::mutex> lock{ this->m_objectLock };
    for (auto& iter : m_tasks)
    {
        t.add(iter.second->getName());
        t.add(utils::to_hexstring(iter.second->getThreadId()));
        t.add(utils::to_hexstring(iter.second.get()));
        t.add(status_to_string(iter.second->isRunning())).endOfRow();
    }
    return OK;
}
PROCESS_IMPL_DESC(TaskManager, process)
{
    PROCESS_BEGIN()
    PROCESS_CALL(CMD_SYS_SHUTDOWN, sysShutdown)
    PROCESS_END(RET_ERROR)
}
PROCESS_IMPL_DESC(TaskManager, sysShutdown)
{
    return destory();
}
STATUS TaskManager::preInit()
{
    return OK;
}
STATUS TaskManager::postInit()
{
    return registerMessageListener(MODULE_TASK_MGR);
}
STATUS  TaskManager::destory()
{
    std::lock_guard<std::mutex> lock(m_objectLock);
    m_tasks.clear();
    return OK;
}
REG_TO_FRAMEWORK(TaskManager, MODULE_TASK_MGR)
